const Koa = require("koa");
const KoaStatic = require("koa-static");
const Router = require("koa-router");
const session = require("koa-session");
const bodyParser = require("koa-bodyparser");
const path = require("path");
const logger = require("./utils/logger");
const { readArgs } = require("./utils/readArgs");

const swaggerJSDoc = require("swagger-jsdoc");
const { koaSwagger } = require("koa2-swagger-ui");

// 加载 Swagger 配置
const swaggerSpec = swaggerJSDoc(require("./swagger.config.js"));

// 尝试将读取args.json到的字符串解析为 JSON 对象
let args = readArgs();

const app = new Koa();

const mainRouter = new Router(); // 创建一个主路由器来组合子路由器

// 暴露 Swagger JSON 端点
mainRouter.get("/swagger.json", (ctx) => {
  ctx.set("Content-Type", "application/json");
  ctx.body = swaggerSpec;
});

// 配置 Swagger UI 页面
mainRouter.get(
  "/docs",
  koaSwagger({
    routePrefix: false, // 禁用自动路由前缀
    swaggerOptions: {
      url: "/swagger.json", // 指定 Swagger JSON 地址
    },
  })
);
// 使用 body parser 中间件，用于解析 POST 请求的参数
app.use(bodyParser());

// 集成 session
app.keys = [`${args.password}`]; // 'some secret hurr'
const CONFIG = {
  key: "koa:sess" /** (string) cookie key (default is koa:sess) */,
  /** (number || 'session') maxAge in ms (default is 1 days) */
  /** 'session' will result in a cookie that expires when session/browser is closed */
  /** Warning: If a session cookie is stolen, this cookie will never expire */
  maxAge: 0.5 * 3600 * 1000, // 0.5h cookie的具体过期时间；
  overwrite: true /** (boolean) can overwrite or not (default true) */,
  httpOnly: true /** (boolean) httpOnly or not (default true) */,
  signed: true /** (boolean) signed or not (default true) */,
  rolling: false /** (boolean) Force a session identifier cookie to be set on every response. The expiration is reset to the original maxAge, resetting the expiration countdown. (default is false) */,
  renew: false /** (boolean) renew session when session is nearly expired, so we can always keep user logged in. (default is false)*/,
};

app.use(session(CONFIG, app));

// 创建一个HTTP服务器，并将koa应用程序作为回调函数传入
const server = require("http").Server(app.callback());

//路由模块
const runShell = require("./routes/runShell");
const runShellModel = new runShell(server);
runShellModel.init();

const runShellRouter = runShellModel.router;
const fileRouter = require("./routes/file");
const nginxRouter = require("./routes/nginx");
const userRouter = require("./routes/user");

//使用Koa的router中间件来处理路由,注册子路由
//router.routes()注册所有定义的路由，router.allowedMethods()确保HTTP方法被正确处理。
//app.use(router.routes()).use(router.allowedMethods());
mainRouter.use(runShellRouter.routes()).use(runShellRouter.allowedMethods());
mainRouter.use(fileRouter.routes()).use(fileRouter.allowedMethods());
mainRouter.use(nginxRouter.routes()).use(nginxRouter.allowedMethods());
mainRouter.use(userRouter.routes()).use(userRouter.allowedMethods());

app.use(mainRouter.routes()).use(mainRouter.allowedMethods());

// 使用KoaStatic中间件来提供静态文件服务，这里指定静态文件的目录为项目根目录下的"frontend"文件夹
let staticPath = path.resolve(__dirname, "../frontend");
console.log("静态站点地址 ======> ", staticPath);
app.use(new KoaStatic(staticPath));

server.listen(args.port, () => {
  console.log("服务启动成功");
  logger && logger.info(`服务监听 ${args.port} 端口`);
});
